<?php
/**
 * Author: Traveler
 * Time  : 2021/9/4 14:42
 */

namespace sunshine\traits;


use app\ErrorCode;
use sunshine\basic\BaseModel;
use sunshine\basic\RestService;
use sunshine\exceptions\ApiException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * Trait ServiceOperationTrait
 *
 * @package sunshine\traits
 * @property BaseModel $model Model实例
 * @mixin RestService
 */
trait ServiceRestTrait
{
    /**
     * 公共方法：获取列表
     *
     * @param array $search
     * @return array
     */
    public function select(array $search = []): array
    {
        // 分页和搜索
//        $this->queryConditions['withSearch'] = $this->filterInvalidParam($search);
        $search = $this->filterInvalidParam($search);
        [$page, $pageSize] = $this->getPagination($search);

        // 查询
        $query = $this->model->makeDynamicQuery($this->makeConditions(), $search, $page, $pageSize);

        // 结果
        $list  = $query->select()->toArray();
        $total = $query->count();

        // 处理结果
        if ($this->isTreeResult) {
            $list = list_to_tree($list);
        }

        return compact('list', 'page', 'pageSize', 'total');
    }

    /**
     * 公共方法：获取单条数据(形参$id会覆盖$where中的id)
     *
     * @param int|null $id
     * @return array
     */
    public function find(?int $id = null): array
    {
        return $this->model->makeDynamicQuery($this->makeConditions())->findOrEmpty($id)->toArray();
    }

    /**
     * 公共方法：创建
     *
     * @param array $data
     * @return bool
     */
    public function create(array $data): bool
    {
        return !$this->model->create($data)->isEmpty();
    }

    /**
     * 公共方法：修改
     *
     * @param int   $id
     * @param array $data
     * @return bool
     */
    public function update(int $id, array $data): bool
    {
        $result = $this->model->find($id);
        if (!$result) {
            throw new ApiException(ErrorCode::DATA_NOT_FOUND);
        }

        return $result->save($data);
    }

    /**
     * 公共方法：删除
     *
     * @param int        $id
     * @param array|null $relation
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function delete(int $id, ?array $relation = null): bool
    {
        $result = $relation ? $this->model->with($relation)->find($id) : $this->model->find($id);
        if (!$result) {
            throw new ApiException(ErrorCode::DATA_NOT_FOUND);
        }

        return $relation ? $result->together($relation)->delete() : $result->delete();
    }
}